package com.fengwk.cv4j.factory;

import com.fengwk.cv4j.view.Var;
import com.fengwk.cv4j.view.View;

/**
 * 视图工厂
 * 
 * @author fengwk
 *
 * @param <T>
 */
public interface ViewFactory<T> {

	/**
	 * 单纯构造一个变量Var</br>
	 * 但在使用直线需要为变量附值{@link Var#assign(T)}
	 * 
	 * @return
	 */
	Var<T> of();
	
	/**
	 * 使用Number创建一个变量</br>
	 * 这是一个从Number映射到相应T视图的方法</br>
	 * 实现时必须考虑到这个映射是否会影响T类型的运算
	 * 
	 * @param num
	 * @return
	 */
	Var<T> of(Number num);
	
	/**
	 * 使用T创建一个变量</br>
	 * 相当于对T对象的一个变量包装{@link Var}
	 * 
	 * @param t
	 * @return
	 */
	Var<T> of(T t);
	
	/**
	 * 使用Number和T对象共同创建一个变量</br>
	 * 这个方法允许创建的变量能够共同继承Number和T的特性</br>
	 * 例如在数组的实现中变量同时继承了Number的值和数组T的形状
	 * 
	 * @param num
	 * @param d
	 * @return
	 */
	Var<T> of(Number num, T d);
	
	/**
	 * v1+v2
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	View<T> add(View<T> v1, View<T> v2);

	/**
	 * v1-v2
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	View<T> sub(View<T> v1, View<T> v2);

	/**
	 * v1*v2
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	View<T> mul(View<T> v1, View<T> v2);
	
	/**
	 * v1/v2
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	View<T> div(View<T> v1, View<T> v2);
	
	/**
	 * v1^v2
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	View<T> pow(View<T> v1, View<T> v2);
	
	/**
	 * exp(v1)
	 * 
	 * @param v1
	 * @return
	 */
	View<T> exp(View<T> v);
	
	/**
	 * log(v1)
	 * 
	 * @param v1
	 * @return
	 */
	View<T> log(View<T> v);
	
	/**
	 * 求负
	 * 
	 * @param v
	 * @return
	 */
	View<T> neg(View<T> v);
	
	/**
	 * 求均值
	 * 
	 * @param vs
	 * @return
	 */
	View<T> mean(@SuppressWarnings("unchecked") View<T>...vs);
    
    /**
     * 求和
     * 
     * @param vs
     * @return
     */
	View<T> sum(@SuppressWarnings("unchecked") View<T>...vs);
	
	/**
	 * 取模
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	View<T> mod(View<T> v1, View<T> v2);
    
    /**
     * 绝对值
     * 
     * @param v
     * @return
     */
	View<T> abs(View<T> v);
    
    /**
     * 取符号位
     * 
     * @param v
     * @return 
     */
	View<T> sign(View<T> v);
    
    /**
     * 最大值
     * 
     * @param cvs
     * @return
     */
	View<T> max(@SuppressWarnings("unchecked") View<T>...vs);
    
    /**
     * 最小值
     * 
     * @param cvs
     * @return
     */
	View<T> min(@SuppressWarnings("unchecked") View<T>...vs);
    
    /**
     * 三角函数cosine
     * 
     * @param v
     * @return
     */
	View<T> cos(View<T> v);
    
    /**
     * 三角函数sine
     * 
     * @param v
     * @return
     */
	View<T> sin(View<T> v);
    
    /**
     * 三角函数tan
     * 
     * @param v
     * @return
     */
	View<T> tan(View<T> v);
    
    /**
     * 三角函数atan
     * 
     * @param v
     * @return
     */
	View<T> atan(View<T> v);
    
    /**
     * 四舍五入
     * 
     * @param v
     * @return
     */
	View<T> round(View<T> v);
    
    /**
     * 向下取整
     * 
     * @param v
     * @return
     */
	View<T> floor(View<T> v);
    
    /**
     * 向上取整
     * 
     * @param v
     * @return
     */
	View<T> ceil(View<T> v);
	
	/**
	 * 相等
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	View<T> equals(View<T> v1, View<T> v2);
	
}
